package samplejava.compiler;

import java.util.ArrayList;

public class ETipo_Pointer extends ETipo {
	
    ArrayList<ETipo> puntero; //por defecto sera de tamaño 1
    int i; //indice al que apunta

    
	public ETipo_Pointer(ArrayList<ETipo> puntero, int indice) {
		super(Tipos.POINTER);
		this.puntero = puntero; //se iguala a la direccion de memoria
		this.i = indice;
	}
	
	public ETipo_Pointer(ArrayList<ETipo> puntero) {
		this(puntero, 0);
	}
	
	public ETipo_Pointer(ETipo etipo) {
		super(Tipos.POINTER);
		this.puntero = new ArrayList<ETipo>(); //ETipo_Int por defecto
		i = 0;
		puntero.add(etipo);
	}
	
	public ETipo_Pointer() {
		this(new ETipo_Int(0));
	}
	
	/*public ETipo_Pointer(int tipo_apuntado) {
		
		switch (tipo_apuntado) {
			case Tipos.INT: this(ETipo_Int()); break;
			case Tipos.LONG: this(ETipo_Long()); break;
			case Tipos.FLOAT: this.puntero = new ETipo_Float(tipo_apuntado); break;
			case Tipos.POINTER: this.puntero = new ETipo_Pointer(); break;
			default: this.puntero = new ETipo_Int(); //por poner algo xD
		} 

	}*/
	
	
	public ETipo getApuntado() {
		return puntero.get(this.i); //devuelve el primero
	}
	
	public int getIndice() {
		return i;
	}

    //public void incIndice();
	//public void decIndice();
	
	public void setIndice(int i) {
		if (i >= puntero.size())
			i = puntero.size() - 1; //apunta al ultimo
		else
			this.i = i;
	}

	public ArrayList<ETipo> getPuntero() {
		return this.puntero;
	}
	public void setPuntero(ArrayList<ETipo> puntero) {
		this.puntero = puntero; //iguala direccion de mem
	}
	
	public int getIdApuntado() {
		return getApuntado().getIdTipo();
	}
	
	public void setNewPuntero(int tipo_apuntado, int n) { //tamaño n
		this.puntero.clear(); //vacia
		
		switch (tipo_apuntado) {				
			case Tipos.LONG:
				for (int j = 0; j < n; j++) 
					this.puntero.add(new ETipo_Long()); 
				break;
				
			case Tipos.FLOAT:
				for (int j = 0; j < n; j++) 
					this.puntero.add(new ETipo_Float()); 
				break;
				
			//case Tipos.POINTER: this.puntero = new ETipo_Pointer(); break;
			//case Tipos.VOID
				
			default: //tambien case Tipos.INT
				for (int j = 0; j < n; j++) 
					this.puntero.add(new ETipo_Int()); 
				break;
		}
		
		this.i = 0;
	}
	
	
	public void setNewPuntero(int tipo_apuntado) {
		setNewPuntero(tipo_apuntado, 1); //tamaño 1
	}
	
	public void setNewPuntero(int tipo_apuntado, long value, long decimal) {
		setNewPuntero(tipo_apuntado); //tamaño 1
		setValue(value); //puntero.get(i).setValue
		setDecimalValue(decimal);
	}
	
	public String toString() {
		String cadena = " -> ";
		if (puntero.size() <= i) //(puntero == null)
			cadena += "null";
		else
			cadena += puntero.get(i).toString();
		return cadena;
	}
	
	
	//estos metodos se referiran a los valores del apuntado (el elemento del INDICE)
	public long getValue() { 
		if (puntero.size() >= i)
			if ((puntero.get(i).getIdTipo() == Tipos.INT) || (puntero.get(i).getIdTipo() == Tipos.LONG) || (puntero.get(i).getIdTipo() == Tipos.FLOAT))
				return puntero.get(i).getValue();
		
		return NIL;
	}
	
	public void setValue(long value) {
		if (puntero.size() >= i) //(puntero != null)
			if ((puntero.get(i).getIdTipo() == Tipos.INT) || (puntero.get(i).getIdTipo() == Tipos.LONG) || (puntero.get(i).getIdTipo() == Tipos.FLOAT))
				puntero.get(i).setValue(value); //XXX: comprobar que se actualiza
	}
	
	public long getDecimalValue() { 		
		if (puntero.size() >= i)
			if (puntero.get(i).getIdTipo() == Tipos.FLOAT)
				return puntero.get(i).getDecimalValue();
		
		return NIL;
	}
	
	public void setDecimalValue(long value) {
		if (puntero.size() >= i)
			if (puntero.get(i).getIdTipo() == Tipos.FLOAT)
				puntero.get(i).setDecimalValue(value);
	}

}
